package modeles;

public class CFB {
	
	int[] IV;	
	DES_Encrypt des;
	
	public CFB(DES_Encrypt des) {
		this.des = des;
		this.IV = creerIV();
	}
	
	public int[] creerIV(){
		int[] IV = new int[64];
		for (int i = 0; i<64; i++){
			IV[i] = (int) (Math.random() + 0.5);
		}		 
		return IV;
	}
	
	public int[] decrypt(int[] key_bit, int[] message_bit) {
		int nbBlocs = message_bit.length/64; //bloc de 64 bits
		int debut=0, fin=64;
		int[] bloc_bit;
		int[] bloc_crypt = null;
		int[][] total = new int[nbBlocs][64];
		int[] temp = null;
		//pour chaque bloc
		for(int i=0; i<nbBlocs; i++){
			bloc_bit = new int[64];
			//choix du bloc
			int i_encours = 0;
			for (int i_bloc=debut; i_bloc<fin; i_bloc++){
				bloc_bit[i_encours]= message_bit[i_bloc];
				i_encours++;
			}
			des.printTab(bloc_bit, "bloc en cours");
			
			//bloc_crypt = des.doEncryptBloc(bloc_bit, key_bit, false);
			
			if (i==0){ //premiers blocs
				bloc_crypt = des.doEncryptBloc(IV, key_bit, true);
			}
			else{
				bloc_crypt = des.doEncryptBloc(temp, key_bit, true); //encrypt Ci-1
			}	
			
			//XOR
			bloc_crypt = des.XOR(bloc_crypt, bloc_bit); //Xor entre Ci et E(ci-1)
			
			temp = bloc_bit; //Ci-1
			total[i] = bloc_crypt;
			//passage au prochain bloc
			debut=fin;
			fin+=64;
			
		}
		
		String titre = "encrypt";
			
		for (int i=0; i<nbBlocs; i++)
			des.printTab(total[i], "texte total "+titre+" bloc "+i);

		int[] bloc_fin = new int[nbBlocs*64]; 

		int index_gen = 0;
		for (int i=0; i<nbBlocs; i++){
			for(int j=0; j<64; j++){
				bloc_fin[index_gen] = total[i][j];
				index_gen++;
			}
		}
		
		
		System.out.println("res : "+des.binToString(bloc_fin, nbBlocs));
		DES_Encrypt.retour_decrypt = des.binToString(bloc_fin, nbBlocs);
		//des.TESTbinToString(bloc_fin, nbBlocs);
		return bloc_fin;
		
	}

	public int[] encrypt(int[] key_bit, int[]message_bit){
		int nbBlocs = message_bit.length/64; //bloc de 64 bits
		int debut=0, fin=64;
		int[] bloc_bit;
		int[] bloc_crypt = null;
		int[][] total = new int[nbBlocs][64];
		int[] temp = null;
		//pour chaque bloc
		for(int i=0; i<nbBlocs; i++){
			bloc_bit = new int[64];
			//choix du bloc
			int i_encours = 0;
			for (int i_bloc=debut; i_bloc<fin; i_bloc++){
				bloc_bit[i_encours]= message_bit[i_bloc];
				i_encours++;
			}
			des.printTab(bloc_bit, "bloc en cours");

			
			
			if (i==0){
				bloc_crypt = des.doEncryptBloc(IV, key_bit, true);	
			}
			else
				bloc_crypt = des.doEncryptBloc(bloc_crypt, key_bit, true); //bloc crypt précédent
				
			bloc_crypt = des.XOR(bloc_crypt, bloc_bit); //XOR entre previous crypt et plain courant
				
			temp = bloc_crypt; //Ci-1
			total[i] = bloc_crypt;
			//passage au prochain bloc
			debut=fin;
			fin+=64;
		}
		
		String titre = "crypt";
		
		for (int i=0; i<nbBlocs; i++)
			des.printTab(total[i], "texte total "+titre+" bloc "+i);

		int[] bloc_fin = new int[nbBlocs*64]; 

		int index_gen = 0;
		for (int i=0; i<nbBlocs; i++){
			for(int j=0; j<64; j++){
				bloc_fin[index_gen] = total[i][j];
				index_gen++;
			}
		}
		
		DES_Encrypt.retour_decrypt = des.binToString(bloc_fin, nbBlocs);
		//des.TESTbinToString(bloc_fin, nbBlocs);
		return bloc_fin;
	}
	

}
